package org.ht.util;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Issao Hanaoka Junior
 */
public class ValidadorCpfCnpj {

    public ValidadorCpfCnpj() {
    }

    private static class ValidadorCpfHolder {

        public static final ValidadorCpfCnpj INSTANCE = new ValidadorCpfCnpj();
    }

    public static ValidadorCpfCnpj getInstance() {
        return ValidadorCpfHolder.INSTANCE;
    }

    public static String extraiNaoDigitos(String cpfCnpj) {

        List<String> strList = new ArrayList();

        for (int i = 0; i < cpfCnpj.length(); i++) {
            if (Character.isDigit(cpfCnpj.charAt( i ))) {
                strList.add(String.valueOf(cpfCnpj.charAt( i )));
            }
        }

        StringBuilder out = new StringBuilder();
        for (Object o : strList) {
            out.append(o.toString());            
        }
        return out.toString();
    }    

    public static boolean validaCPF(String cpf) {

        cpf = extraiNaoDigitos(cpf);

        if (cpf.length() != 11 || cpf.equals("00000000000")) {
            return false;
        }

        String numDig = cpf.substring(0, 9);
        return calcDigVerif(numDig).equals(cpf.substring(9, 11));
    }

    public static boolean validaCNPJ(String cnpj) {

        cnpj = extraiNaoDigitos(cnpj);

        if ((cnpj == null) || (cnpj.length() != 14)) {
            return false;
        }

        Integer digito1 = calcularDigito(cnpj.substring(0, 12), pesoCNPJ);
        Integer digito2 = calcularDigito(cnpj.substring(0, 12) + digito1, pesoCNPJ);
        return cnpj.equals(cnpj.substring(0, 12) + digito1.toString() + digito2.toString());
    }
    private static final int[] pesoCNPJ = {6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};

    private static String calcDigVerif(String num) {
        Integer primDig, segDig;
        int soma = 0, peso = 10;
        for (int i = 0; i < num.length(); i++) {
            soma += Integer.parseInt(num.substring(i, i + 1)) * peso--;
        }

        if (soma % 11 == 0 | soma % 11 == 1) {
            primDig = new Integer(0);
        } else {
            primDig = new Integer(11 - (soma % 11));
        }

        soma = 0;
        peso = 11;
        for (int i = 0; i < num.length(); i++) {
            soma += Integer.parseInt(num.substring(i, i + 1)) * peso--;
        }

        soma += primDig.intValue() * 2;
        if (soma % 11 == 0 | soma % 11 == 1) {
            segDig = new Integer(0);
        } else {
            segDig = new Integer(11 - (soma % 11));
        }

        return primDig.toString() + segDig.toString();
    }

    private static int calcularDigito(String str, int[] peso) {
        int soma = 0;
        for (int indice = str.length() - 1, digito; indice >= 0; indice--) {
            digito = Integer.parseInt(str.substring(indice, indice + 1));
            soma += digito * peso[peso.length - str.length() + indice];
        }
        soma = 11 - soma % 11;
        return soma > 9 ? 0 : soma;
    }
}
